/*
 * LineManager.cpp
 *
 *  Created on: 2012-9-9
 *      Author: yangentao@gmail.com
 */

#include "LineManager.h"
lineListener::~lineListener() {
}

LineManager::LineManager() {
	vec.append(0);
	vec.append(INT_MAX); //the last element , usefull
}
void LineManager::dump() {
	cout << "Length: " << count() << endl;
	cout << "[";
	for (int i = 0; i < count(); ++i) {
		cout << vec[i] << " ";
	}
	cout << "]" << endl;
}
int LineManager::findLine(int position) {
	//[0**************MAX_INT]
	if (position < 0) {
		throw IndexOutOfBoundException();
	}
	int n = binarySearch(vec.getBufferRead(), vec.size(), position );
	if(n < 0){
		n = ~n;
		--n;
	}
	return n;
}
void LineManager::parseCrLf(const String& text, Vector<int>& lines, int delta) {
	for (int i = 0; i < text.length(); ++i) {
		if (text[i] == 13) { // no \n fllow by \r
			if (i + 1 < text.length()) {
				if (text[i + 1] != 10) {
					lines.append(i + delta);
				}
			}
		} else if (text[i] == 10) {
			lines.append(i + delta);
		}
	}
}

void LineManager::onTextReplaced(int from, const String& removeText, const String& insertText) {
	int removeLength = removeText.length();
	if (from < 0 || removeLength < 0) {
		throw NegtiveIndexException();
	}
	int lineto = findLine(from + removeLength);
	int delta = insertText.length() - removeLength;
	//[lineto +1, count) has no effect
	if (lineto + 1 < count()) {
		vec.rangeAdd(lineto + 1, count(), delta);
	}
	Vector<int> newlines;
	parseCrLf(insertText, newlines, from + 1);
	int linefrom = findLine(from);	//exclude linefrom
	vec.replace(linefrom + 1, max(0, lineto - linefrom), newlines);
}

